package com.miyake.dsp.osa.lab;

import com.miyake.dsp.analyzer.FftSetting;
import com.miyake.dsp.analyzer.PeakSearchSetting;
import com.miyake.dsp.common.EdgeDetectorSetting;
import com.miyake.dsp.converter.MovingAverageSetting;
import com.miyake.dsp.filter.FilterSetting;
import com.miyake.dsp.filter.FilterSetting.FilterAlgo;
import com.miyake.dsp.filter.FilterSetting.FilterType;
import com.miyake.dsp.generator.FpLdSetting;
import com.miyake.dsp.generator.GaussSetting;
import com.miyake.dsp.generator.NoiseSetting;
import com.miyake.dsp.generator.PulseSetting;
import com.miyake.dsp.osa.OsaSetting;
import com.miyake.dsp.osa.lab.ChartSettingEx.YAxisType;
import com.miyake.dsp.osa.lab.wrapper.AmplifierWrapper;
import com.miyake.dsp.osa.lab.wrapper.AutoSettingWrapper;
import com.miyake.dsp.osa.lab.wrapper.ChartExWrapper;
import com.miyake.dsp.osa.lab.wrapper.ChartWrapper;
import com.miyake.dsp.osa.lab.wrapper.ConvolutionWrapper;
import com.miyake.dsp.osa.lab.wrapper.DecibelWrapper;
import com.miyake.dsp.osa.lab.wrapper.DiffWrapper;
import com.miyake.dsp.osa.lab.wrapper.EdgeDetectorWrapper;
import com.miyake.dsp.osa.lab.wrapper.ExtractYWrapper;
import com.miyake.dsp.osa.lab.wrapper.FftWrapper;
import com.miyake.dsp.osa.lab.wrapper.FilterWrapper;
import com.miyake.dsp.osa.lab.wrapper.FittingWrapper;
import com.miyake.dsp.osa.lab.wrapper.FpLdWrapper;
import com.miyake.dsp.osa.lab.wrapper.GaussWrapper;
import com.miyake.dsp.osa.lab.wrapper.GaussianFilterWrapper;
import com.miyake.dsp.osa.lab.wrapper.HigeDetectorWrapper;
import com.miyake.dsp.osa.lab.wrapper.HistogramWrapper;
import com.miyake.dsp.osa.lab.wrapper.LimiterWrapper;
import com.miyake.dsp.osa.lab.wrapper.MathWrapper;
import com.miyake.dsp.osa.lab.wrapper.MedianFilterWrapper;
import com.miyake.dsp.osa.lab.wrapper.MovingAverageWrapper;
import com.miyake.dsp.osa.lab.wrapper.Ms9740aCsvWrapper;
import com.miyake.dsp.osa.lab.wrapper.Ms9740aWrapper;
import com.miyake.dsp.osa.lab.wrapper.NoiseDetector2Wrapper;
import com.miyake.dsp.osa.lab.wrapper.NoiseDetectorWrapper;
import com.miyake.dsp.osa.lab.wrapper.NoiseGeneratorWrapper;
import com.miyake.dsp.osa.lab.wrapper.NoiseGateWrapper;
import com.miyake.dsp.osa.lab.wrapper.OtdrSimulatorRxExWrapper;
import com.miyake.dsp.osa.lab.wrapper.OtdrSimulatorRxWrapper;
import com.miyake.dsp.osa.lab.wrapper.OtdrSimulatorTxWrapper;
import com.miyake.dsp.osa.lab.wrapper.PeakSearch2Wrapper;
import com.miyake.dsp.osa.lab.wrapper.PeakSearchWrapper;
import com.miyake.dsp.osa.lab.wrapper.PowerWrapper;
import com.miyake.dsp.osa.lab.wrapper.PulseGeneratorWrapper;
import com.miyake.dsp.osa.lab.wrapper.ScilabWrapper;
import com.miyake.dsp.osa.lab.wrapper.EdgeFilterWrapper;
import com.miyake.dsp.osa.lab.wrapper.SortWrapper;
import com.miyake.dsp.osa.lab.wrapper.Sr4731Wrapper;
import com.miyake.dsp.osa.lab.wrapper.TextReaderWrapper;
import com.miyake.dsp.osa.lab.wrapper.UnsharpMaskWrapper;
import com.miyake.dsp.osa.lab.wrapper.ZoneAverageWrapper;
import com.miyake.dsp.osa.lab.wrapper.MicroOtdrWrapper;
import com.miyake.dsp.otdr.OtdrRxExSetting;
import com.miyake.dsp.otdr.OtdrRxSetting;
import com.miyake.dsp.otdr.OtdrSetting;
import com.miyake.dsp.otdr.RealOtdrSetting;

public class LabFactory {
	private static LabFactory instance;
	private LabContainer activeContainer;
	private LabFactory() {
		
	}
	
	public static LabFactory getInstance() {
		if (instance == null) {
			instance = new LabFactory();
		}
		return instance;
	}
	
	public LabContainer createFFT() {
		FftSetting setting = new FftSetting();
		
		Calculator fft = new FftWrapper(setting);
		double[] t = {1,4,2,3,4};
		return new LabContainer(fft);		
	}
	
	public LabContainer createFitting() {
		FittingSetting2 setting = new FittingSetting2();
		setting.setFormula("y=x(1)+x(2)*t");
		Calculator fitting = new FittingWrapper(setting);	
		return new LabContainer(fitting);
	}
	
	public LabContainer createFilter() {
		FilterSetting setting = new FilterSetting();
		setting.setFilterAlgo(FilterAlgo.Chebyshev1);
		setting.setFilterType(FilterType.Lowpass);
		setting.setCutoff1(10);
		setting.setFrequency(100);
		setting.setOrder(2);
		FilterWrapper filter = new FilterWrapper(setting);
		return new LabContainer(filter);
	}
	
	public LabContainer createPulseGenerator() {
		PulseSetting setting = new PulseSetting(1e-7, 1, 10, 1e9);
		PulseGeneratorWrapper pulse = new PulseGeneratorWrapper(setting);
		return new LabContainer(pulse);
	}
	
	public LabContainer createConvolution() {
		ConvolutionWrapper conv = new ConvolutionWrapper();
		return new LabContainer(conv);
	}
	
	public LabContainer createDiff() {
		DiffWrapper diff = new DiffWrapper();
		return new LabContainer(diff);
	}

	public LabContainer createOtdrTx() {
		//OtdrImpulseResponseSetting setting = new OtdrImpulseResponseSetting(1550, 1);
		//OtdrWrapper otdr = new OtdrWrapper(setting);
		
		OtdrSetting setting = new OtdrSetting();
		setting.setSamplingFrequency(1e8);
		setting.setDistanceRange(25);
		setting.setPulseLevel(1);
		setting.setWavelength(1550);
		setting.setPulseWidth(50);
		setting.setReceiverBandwidth(1e7);
		setting.setReceiverNoise(1e-6);
		OtdrSimulatorTxWrapper otdr = new OtdrSimulatorTxWrapper(setting);
		LabContainer ret = new LabContainer(otdr);
		
		if (activeContainer != null) {
			if (this.activeContainer.getCalculatorName().equals("AutoSettingWrapper")) {
				ret.setInConnector(OtdrSimulatorTxWrapper.IN_DISTANCE, activeContainer.getOutConnector(AutoSettingWrapper.OUTPUT_DISTANCE));
				ret.setInConnector(OtdrSimulatorTxWrapper.IN_PULSE, activeContainer.getOutConnector(AutoSettingWrapper.OUTPUT_PULSEWIDTH));
			}
		}
		return ret;
	}
	
	public LabContainer createOtdrRxEx() {
		OtdrRxExSetting setting = new OtdrRxExSetting();
		setting.setCeiling(1);
		setting.setNoise(1e-6);
		setting.setSamplingFrequency(1e8);
		setting.setBandwidth00dB(1e6);
		setting.setBandwidth03dB(2e6);
		setting.setBandwidth06dB(3e6);
		setting.setBandwidth09dB(4e6);
		setting.setBandwidth12dB(5e6);
		setting.setBandwidth15dB(6e6);
		setting.setBandwidth18dB(7e6);
		setting.setBandwidth21dB(8e6);
		return new LabContainer(new OtdrSimulatorRxExWrapper(setting));
	}
	
	public LabContainer createOtdrRx() {
		OtdrRxSetting setting = new OtdrRxSetting();
		setting.setCeiling(1);
		setting.setNoise(1e-6);
		setting.setSamplingFrequency(1e8);
		setting.setAttenuation(0);
		setting.setCeiling(1);
		setting.setNoise(1e-6);
		setting.setBandwidth(1e7);
		setting.setMovingAverage(1);
		LabContainer ret =  new LabContainer(new OtdrSimulatorRxWrapper(setting));
		if (activeContainer != null) {
			if (this.activeContainer.getCalculatorName().equals("OtdrSimulatorTxWrapper")) {
				ret.setInConnector(OtdrSimulatorRxWrapper.INPUT_LOSS, activeContainer.getOutConnector(OtdrSimulatorTxWrapper.OUT_LOSS));
				ret.setInConnector(OtdrSimulatorRxWrapper.INPUT_FREQUENCY, activeContainer.getOutConnector(OtdrSimulatorTxWrapper.OUT_FREQUENCY));
			}
			if (this.activeContainer.getCalculatorName().equals("AutoSettingWrapper")) {
				ret.setInConnector(OtdrSimulatorRxWrapper.INPUT_ATT, activeContainer.getOutConnector(AutoSettingWrapper.OUTPUT_ATT));
				ret.setInConnector(OtdrSimulatorRxWrapper.INPUT_BANDWIDTH, activeContainer.getOutConnector(AutoSettingWrapper.OUTPUT_BANDWIDTH));
			}
		}
		return ret;
	}

	public LabContainer createSr4731Reader() {
		return new LabContainer(new Sr4731Wrapper(new FileSetting()));
	}
	
	public LabContainer createRealOtdr() {
		return new LabContainer(new MicroOtdrWrapper(new RealOtdrSetting()));
	}
	
	public LabContainer createDecibel() {
		return new LabContainer(new DecibelWrapper(new DecibelSetting(-120)));
	}
	
	public LabContainer createNoiseGate() {
		return new LabContainer(new NoiseGateWrapper(new NoiseRemoverSetting(0)));
	}
	
	public LabContainer createPower() {
		return new LabContainer(new PowerWrapper());
	}
	
	public LabContainer createNoiseGenerator() {
		NoiseSetting setting = new NoiseSetting(1e-6);
		return new LabContainer(new NoiseGeneratorWrapper(setting));
	}
	
	public LabContainer createMs9740aCsv() {
		return new LabContainer(new Ms9740aCsvWrapper(new FileSetting()));
	}
	
	public LabContainer createTextReader() {
		return new LabContainer(new TextReaderWrapper(new FileSetting()));
	}
	
	public LabContainer createPeakSearch() {
		return new LabContainer(new PeakSearchWrapper(new PeakSearchSetting(50, 0.01)));
	}

	public LabContainer createPeakSearch2() {
		return new LabContainer(new PeakSearch2Wrapper(new PeakSearchSetting()));
	}
	
	public LabContainer createChart() {
		return new LabContainer(new ChartWrapper(new ChartSetting(ChartSetting.YAxisType.Linear)));
	}

	public LabContainer createChartEx() {
		LabContainer ret = new LabContainer(new ChartExWrapper(new ChartSettingEx(ChartSettingEx.YAxisType.Linear)));
		if (activeContainer != null) {
			if (this.activeContainer.getCalculatorName().equals("OtdrSimulatorRxExWrapper")) {
				ret.setInConnector(ChartExWrapper.INPUT1_Y, activeContainer.getOutConnector(OtdrSimulatorRxExWrapper.OUT_0DB));
				ret.setInConnector(ChartExWrapper.INPUT2_Y, activeContainer.getOutConnector(OtdrSimulatorRxExWrapper.OUT_3DB));
				ret.setInConnector(ChartExWrapper.INPUT3_Y, activeContainer.getOutConnector(OtdrSimulatorRxExWrapper.OUT_6DB));
				ret.setInConnector(ChartExWrapper.INPUT4_Y, activeContainer.getOutConnector(OtdrSimulatorRxExWrapper.OUT_9DB));
				ret.setInConnector(ChartExWrapper.INPUT5_Y, activeContainer.getOutConnector(OtdrSimulatorRxExWrapper.OUT_12DB));
				ret.setInConnector(ChartExWrapper.INPUT6_Y, activeContainer.getOutConnector(OtdrSimulatorRxExWrapper.OUT_15DB));
				ret.setInConnector(ChartExWrapper.INPUT7_Y, activeContainer.getOutConnector(OtdrSimulatorRxExWrapper.OUT_18DB));
				ret.setInConnector(ChartExWrapper.INPUT8_Y, activeContainer.getOutConnector(OtdrSimulatorRxExWrapper.OUT_21DB));
				((ChartSettingEx)ret.getSetting()).setOffset1(0);
				((ChartSettingEx)ret.getSetting()).setOffset2(3);
				((ChartSettingEx)ret.getSetting()).setOffset3(6);
				((ChartSettingEx)ret.getSetting()).setOffset4(9);
				((ChartSettingEx)ret.getSetting()).setOffset5(12);
				((ChartSettingEx)ret.getSetting()).setOffset6(15);
				((ChartSettingEx)ret.getSetting()).setOffset7(18);
				((ChartSettingEx)ret.getSetting()).setOffset8(21);
				((ChartSettingEx)ret.getSetting()).setyAxisType(YAxisType.dB);
			}
		}
		return ret;
	}
	
	public LabContainer createNoiseDetector() {
		return new LabContainer(new NoiseDetectorWrapper());
	}
	
	public LabContainer createNoiseDetector2() {
		return new LabContainer(new NoiseDetector2Wrapper());
	}
	
	public LabContainer createMath() {
		return new LabContainer(new MathWrapper(new MathSetting2(MathSetting2.MathType.MINUS)));
	}
	
	public LabContainer createMovingAverage() {
		return new LabContainer(new MovingAverageWrapper(new MovingAverageSetting(3)));
	}
	
	public LabContainer createSort() {
		return new LabContainer(new SortWrapper());
	}
	
	public LabContainer createExtractY() {
		return new LabContainer(new ExtractYWrapper(new ExtractSetting(0, 1e-6)));
	}
	
	public LabContainer createEdgeDetectorWrapper() {
		return new LabContainer(new EdgeDetectorWrapper(new EdgeDetectorSetting(0, 0)));
	}
	
	public LabContainer createLimiter() {
		return new LabContainer(new LimiterWrapper(new LimiterSetting2(1)));
	}
	
	public LabContainer createAmplifier() {
		return new LabContainer(new AmplifierWrapper(new GainSetting(2)));
	}
	
	public LabContainer createAutoSetting() {
		LabContainer ret = new LabContainer(new AutoSettingWrapper(new AutoSetting()));
		ret.addAutoDisabled(AutoSettingWrapper.INPUT_DISTANCE);
		ret.addAutoDisabled(AutoSettingWrapper.INPUT_LOSS);
		return ret;
	}

	public LabContainer createScilab() {
		return new LabContainer(new ScilabWrapper(new ScilabSetting()));
	}
	
	public LabContainer createHistogram() {
		return new LabContainer(new HistogramWrapper(new HistogramSetting()));
	}
	
	public LabContainer createZoneAverage() {
		return new LabContainer(new ZoneAverageWrapper(new ZoneAverageSetting()));
	}
	
	public LabContainer createGaussGenerator() {
		return new LabContainer(new GaussWrapper(new GaussSetting()));
	}
	
	public LabContainer createFpLd() {
		return new LabContainer(new FpLdWrapper(new FpLdSetting()));
	}

	public LabContainer createEdgeFilter() {
		return new LabContainer(new EdgeFilterWrapper(new OperatorSetting()));
	}
	
	public LabContainer createUnsharpMask() {
		return new LabContainer(new UnsharpMaskWrapper());
	}
	
	public LabContainer createGaussianFilter() {
		return new LabContainer(new GaussianFilterWrapper(new GaussSetting()));
	}

	public LabContainer createMedianFilter() {
		return new LabContainer(new MedianFilterWrapper(new MovingAverageSetting(5)));
	}
	
	public LabContainer createMs9740a() {
		return new LabContainer(new Ms9740aWrapper(new OsaSetting()));
	}
	
	public LabContainer createHigeSearch() {
		return new LabContainer(new HigeDetectorWrapper());
	}
	
	public void setActiveContainer(LabContainer container) {
		this.activeContainer = container;
	}
	
}
